package com.ruibang.glass.sale.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.Constants;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceCreate;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceStatus;
import com.ruibang.glass.common.domain.camunda.BpmTaskApproveReq;
import com.ruibang.glass.common.domain.file.FileBusiness;
import com.ruibang.glass.common.utils.ApproveUserNameUtils;
import com.ruibang.glass.sale.constant.SaleDisputeResultCode;
import com.ruibang.glass.sale.constant.SaleErrorCode;
import com.ruibang.glass.sale.domain.req.GSaleDisputeReq;
import com.ruibang.glass.sale.dto.FileInfoDTO;
import com.ruibang.glass.sale.entity.*;
import com.ruibang.glass.sale.feign.CamundaApi;
import com.ruibang.glass.sale.feign.FileApi;
import com.ruibang.glass.sale.mapper.GSaleDisputeFileMapper;
import com.ruibang.glass.sale.mapper.GSaleDisputeMapper;
import com.ruibang.glass.sale.mapper.GSaleDisputeProductMapper;
import com.ruibang.glass.sale.service.*;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
public class GSaleDisputeServiceImpl extends ServiceImpl<GSaleDisputeMapper, GSaleDispute> implements GSaleDisputeService {

    @Autowired
    private GSaleDisputeProductMapper gSaleDisputeProductMapper;

    @Autowired
    private GSaleDisputeFileMapper gSaleDisputeFileMapper;

    @Autowired
    private FileApi fileApi;

    @Autowired
    private CommonService commonService;

    @Autowired
    private CamundaApi camundaApi;

    @Autowired
    private RedisSingleService rediservice;

    @Autowired
    private SaleShippingApplicationService saleShippingApplicationService;


    private static final String SALE_DISPUTE_FJ = "sale_dispute_fj";//异议附件
    private static final String SALE_DISPUTE_DX_FJ = "sale_dispute_dc_fj";//调查附件
    private static final String finishName = "审批人";

    @Autowired
    private GSaleReturnInventoryService saleReturnInventoryService;

    @Autowired
    private GSaleReturnExchangeOrderService saleReturnExchangeOrderService;


    @Override
    public IPage<GSaleDispute> getPage(GSaleDisputeReq gSaleDisputeReq) {
        IPage<GSaleDispute> page = baseMapper.getPage(new Page<>(gSaleDisputeReq.getPageNo(), gSaleDisputeReq.getPageSize()), gSaleDisputeReq);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return page;
        }
        Map<Object, Object> userMap = rediservice.hmget(RedisKey.USER_GROUP_TYPE);
        Map<Object, Object> departMap = rediservice.hmget(RedisKey.DEPT_GROUP_TYPE);
        List<String> businessKeys = page.getRecords().stream().map(GSaleDispute::getId).collect(Collectors.toList());
        Map<String, Integer> statusMap = null;
        Map<String, String> processMap = null;
        Map<String, String> approveStatusMap = null;
        Map<String, String> userIdMap = null;
        Map<String, String> nodeName = null;
        //获取业务流程状态
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            statusMap = resultBody.getData().stream().collect(Collectors.toMap(BpmProcessInstanceStatus::getBusinessKey, BpmProcessInstanceStatus::getStatus, (s1, s2) -> s1));
            processMap = resultBody.getData().stream().collect(Collectors.toMap(BpmProcessInstanceStatus::getBusinessKey, BpmProcessInstanceStatus::getProcessInstanceId, (s1, s2) -> s1));
            approveStatusMap = resultBody.getData().stream().collect(Collectors.toMap(BpmProcessInstanceStatus::getBusinessKey, BpmProcessInstanceStatus::getResult, (s1, s2) -> s1));
            userIdMap = resultBody.getData()
                    .stream()
                    .filter(status -> status.getUserId() != null)
                    .collect(Collectors.toMap(
                            BpmProcessInstanceStatus::getBusinessKey,
                            BpmProcessInstanceStatus::getUserId,
                            (s1, s2) -> s1
                    ));
            nodeName = resultBody.getData().stream().collect(Collectors.toMap(BpmProcessInstanceStatus::getBusinessKey, BpmProcessInstanceStatus::getNodeName, (s1, s2) -> s1));
        }
        for (GSaleDispute saleDispute : page.getRecords()) {
            saleDispute.setDisputerUnit((String) departMap.get(saleDispute.getDisputerUnit()));
            if (statusMap != null) {
                if (statusMap.get(saleDispute.getId()) != null) {
                    saleDispute.setStatus(statusMap.get(saleDispute.getId()).toString());
                }
            }
            if (processMap != null) {
                saleDispute.setProcessId(processMap.get(saleDispute.getId()));
            }
//            if (approveStatusMap != null) {
//                saleDispute.setApproveStatus(approveStatusMap.get(saleDispute.getId()));
//            }
            if (nodeName != null) {
                saleDispute.setNodeName(nodeName.get(saleDispute.getId()));
            }
            if (approveStatusMap != null) {
                String userId = userIdMap.get(saleDispute.getId());
                if (StringUtils.isNotBlank(userId) && !StringUtils.equals(userId, "null")) {
                    String approveName = ApproveUserNameUtils.getApproveName(userId, userMap);
                    saleDispute.setApproveUser(approveName);
                    saleDispute.setApproveUserId(userId);
                }
            }
        }
        return page;
    }


    @Override
    public void addGSaleDispute(GSaleDispute gSaleDispute) {
        if (CollectionUtils.isEmpty(gSaleDispute.getSaleDisputeProductList())) {
            throw new ServiceException(SaleErrorCode.NO_DISPUTE_ITEM.getCode(), SaleErrorCode.NO_DISPUTE_ITEM.getMsg());
        }
        Map<String, String> aTypeMap = new HashMap<>();
        for (GSaleDisputeProduct gSaleDisputeProduct : gSaleDispute.getSaleDisputeProductList()) {
            if (aTypeMap.get(gSaleDisputeProduct.getTrayId()) != null) {
                throw new ServiceException(SaleErrorCode.SAME_A_TYPE.getCode(), SaleErrorCode.SAME_A_TYPE.getMsg());
            }else {
                aTypeMap.put(gSaleDisputeProduct.getTrayId(),gSaleDisputeProduct.getTrayId());
            }
        }

        baseMapper.insert(gSaleDispute);
        if (CollectionUtils.isNotEmpty(gSaleDispute.getSaleDisputeProductList())) {
            for (GSaleDisputeProduct gSaleDisputeProduct : gSaleDispute.getSaleDisputeProductList()) {
                gSaleDisputeProduct.setDisputeId(gSaleDispute.getId());
                gSaleDisputeProductMapper.insert(gSaleDisputeProduct);
            }
        }
        if (CollectionUtils.isNotEmpty(gSaleDispute.getFilesIds())) {
            FileBusiness fileBusiness = new FileBusiness();
            fileBusiness.setFileIds(gSaleDispute.getFilesIds());
            fileBusiness.setBusinessId(gSaleDispute.getId());
            fileBusiness.setAttribute(SALE_DISPUTE_FJ);
            fileApi.updateBusinessById(fileBusiness);
        }
        BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
        instanceCreate.setBusinessKey(gSaleDispute.getId());
        instanceCreate.setMenuId(gSaleDispute.getMenuId());
        //发起流程
        if (StringUtils.isNotBlank(gSaleDispute.getCreateUserId())) {
            Map<String, Object> variables = new HashMap<>();
            variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_STARTER_USER_ID, gSaleDispute.getCreateUserId());
            variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_BUSINESS_KEY, gSaleDispute.getId());
            variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_MENU_ID, gSaleDispute.getMenuId());
            instanceCreate.setVariables(variables);
        }
        commonService.startProcess(instanceCreate);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGSaleDispute(GSaleDispute gSaleDispute) {

        if (CollectionUtils.isEmpty(gSaleDispute.getSaleDisputeProductList())) {
            throw new ServiceException(SaleErrorCode.NO_DISPUTE_ITEM.getCode(), SaleErrorCode.NO_DISPUTE_ITEM.getMsg());
        }
        Map<String, String> aTypeMap = new HashMap<>();
        for (GSaleDisputeProduct gSaleDisputeProduct : gSaleDispute.getSaleDisputeProductList()) {
            if (aTypeMap.get(gSaleDisputeProduct.getTrayId()) != null) {
                throw new ServiceException(SaleErrorCode.SAME_A_TYPE.getCode(), SaleErrorCode.SAME_A_TYPE.getMsg());
            }else {
                aTypeMap.put(gSaleDisputeProduct.getTrayId(),gSaleDisputeProduct.getTrayId());
            }
        }

        baseMapper.updateById(gSaleDispute);
        fileApi.deleteByBusinessId(gSaleDispute.getId());
        gSaleDisputeProductMapper.delete(Wrappers.<GSaleDisputeProduct>lambdaQuery().eq(GSaleDisputeProduct::getDisputeId, gSaleDispute.getId()));
        if (CollectionUtils.isNotEmpty(gSaleDispute.getFilesIds())) {
            FileBusiness fileBusiness = new FileBusiness();
            fileBusiness.setFileIds(gSaleDispute.getFilesIds());
            fileBusiness.setBusinessId(gSaleDispute.getId());
            fileBusiness.setAttribute(SALE_DISPUTE_FJ);
            fileApi.updateBusinessById(fileBusiness);
        }
        if (CollectionUtils.isNotEmpty(gSaleDispute.getFilesDCIds())) {
            FileBusiness fileBusiness = new FileBusiness();
            fileBusiness.setFileIds(gSaleDispute.getFilesDCIds());
            fileBusiness.setBusinessId(gSaleDispute.getId());
            fileBusiness.setAttribute(SALE_DISPUTE_DX_FJ);
            fileApi.updateBusinessById(fileBusiness);
        }
        if (CollectionUtils.isNotEmpty(gSaleDispute.getSaleDisputeProductList())) {
            for (GSaleDisputeProduct gSaleDisputeProduct : gSaleDispute.getSaleDisputeProductList()) {
                gSaleDisputeProduct.setDisputeId(gSaleDispute.getId());
                gSaleDisputeProductMapper.insert(gSaleDisputeProduct);
            }
        }
//        //当流程 审批通过时 生成出库 入库单
//        Map<String, String> nodeName = null;
//        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Arrays.asList(gSaleDispute.getId()));
//        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
//            nodeName = resultBody.getData().stream().collect(Collectors.toMap(BpmProcessInstanceStatus::getBusinessKey, BpmProcessInstanceStatus::getNodeName, (s1, s2) -> s1));
//        }
        //当流程结束时 生成发货申请
//        if (StringUtils.isNotBlank(gSaleDispute.getDisputeResult())) {
//            //校验处理结果
//            if (gSaleDispute.getDisputeResult().contains(SaleDisputeResultCode.CHANGE_PRODUCT.getMsg())) {
//                // 生成退货发货单
//                saleReturnExchangeOrderService.addGSaleReturnExchangeOrder(getGSaleReturnExchangeOrder(gSaleDispute));
//                // 生成退货入库单
//                saleReturnInventoryService.saveGSaleReturnInventory( getGSaleReturnInventory(gSaleDispute));
//            }
//            if (gSaleDispute.getDisputeResult().contains(SaleDisputeResultCode.ADD_PRODUCT.getMsg())) {
//                // 生成退货发货单
//                saleReturnExchangeOrderService.addGSaleReturnExchangeOrder(getGSaleReturnExchangeOrder(gSaleDispute));
//            }
//            if (gSaleDispute.getDisputeResult().contains(SaleDisputeResultCode.BACK_PRODUCT.getMsg())) {
//                // 生成退货入库单
//                saleReturnInventoryService.saveGSaleReturnInventory( getGSaleReturnInventory(gSaleDispute));
//            }
//            if (gSaleDispute.getDisputeResult().contains(SaleDisputeResultCode.COMPENSATE_MONEY.getMsg())) {
//
//            }
//        }
    }
    //生成退货单 发货单
//    public GSaleReturnExchangeOrder getGSaleReturnExchangeOrder(GSaleDispute gSaleDispute){
//        Map<Object, Object> userMap = rediservice.hmget(RedisKey.USER_GROUP_TYPE);
//        String returnNumber = StringGeneratorService.generateString();
//        List<GSaleReturnExchangeOrderDetail> gSaleReturnExchangeOrderDetailList = new ArrayList<>();
//        Integer allCount = Constants.ZERO_INT;
//        if (CollectionUtils.isNotEmpty(gSaleDispute.getSaleDisputeProductList())) {
//            for (GSaleDisputeProduct gSaleDisputeProduct : gSaleDispute.getSaleDisputeProductList()) {
//                //生成 退换货单 物品详情
//                SaleShippingApplication saleShippingApplication = saleShippingApplicationService.getOne(Wrappers.<SaleShippingApplication>lambdaQuery()
//                        .eq(SaleShippingApplication::getOrderNumber, gSaleDisputeProduct.getOrderNumber()).orderByDesc(SaleShippingApplication::getOrderNumber).last("limit 1"));
//                GSaleReturnExchangeOrderDetail gSaleReturnExchangeOrderDetail = new GSaleReturnExchangeOrderDetail();
//                gSaleReturnExchangeOrderDetail.setOrderNumber(gSaleDisputeProduct.getOrderNumber());
//                gSaleReturnExchangeOrderDetail.setProductName(gSaleDisputeProduct.getProductName());
//                gSaleReturnExchangeOrderDetail.setProductSpecification(gSaleDisputeProduct.getProductSpecification());
//                gSaleReturnExchangeOrderDetail.setReturnQuantity(gSaleDisputeProduct.getQuantity());
//                if (saleShippingApplication != null) {
//                    gSaleReturnExchangeOrderDetail.setDeliveryDate(saleShippingApplication.getShippingDate());
//                }
//                gSaleReturnExchangeOrderDetail.setTrayId(gSaleDisputeProduct.getTrayId());
//                gSaleReturnExchangeOrderDetail.setGlassId(gSaleDisputeProduct.getGlassId());
//                gSaleReturnExchangeOrderDetail.setIssueDescription(gSaleDisputeProduct.getIssueDescription());
//                gSaleReturnExchangeOrderDetail.setRemark(gSaleDisputeProduct.getRemark());
//                gSaleReturnExchangeOrderDetailList.add(gSaleReturnExchangeOrderDetail);
//                allCount = allCount + gSaleDisputeProduct.getQuantity();
//            }
//        }
//        GSaleReturnExchangeOrder gSaleReturnExchangeOrder = new GSaleReturnExchangeOrder();
//        gSaleReturnExchangeOrder.setReturnNumber(returnNumber);
//        gSaleReturnExchangeOrder.setDisputeNumber(gSaleDispute.getDisputeNumber());
//        gSaleReturnExchangeOrder.setCustomer(gSaleDispute.getDisputerUnit());
//        gSaleReturnExchangeOrder.setCustomer(gSaleDispute.getDisputerUnit());
//        gSaleReturnExchangeOrder.setHandler((String) userMap.get(gSaleDispute.getCreateUserId()));
//        gSaleReturnExchangeOrder.setHandlerId(gSaleDispute.getCreateUserId());
//        gSaleReturnExchangeOrder.setReturnQuantity(allCount);
//
//        gSaleReturnExchangeOrder.setGSaleReturnExchangeOrderDetails(gSaleReturnExchangeOrderDetailList);
//        return gSaleReturnExchangeOrder;
//    }

    // 生成退货单
    public GSaleReturnInventory getGSaleReturnInventory(GSaleDispute gSaleDispute) {
        Map<Object, Object> userMap = rediservice.hmget(RedisKey.USER_GROUP_TYPE);
        String returnNumber = StringGeneratorService.generateString();
        List<SaleReturnInventoryProduct> gSaleReturnExchangeOrderDetailList = new ArrayList<>();
        BigDecimal allCount = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(gSaleDispute.getSaleDisputeProductList())) {
            for (GSaleDisputeProduct gSaleDisputeProduct : gSaleDispute.getSaleDisputeProductList()) {
                //生成 退换货单 物品详情
                SaleShippingApplication saleShippingApplication = saleShippingApplicationService.getOne(Wrappers.<SaleShippingApplication>lambdaQuery()
                        .eq(SaleShippingApplication::getOrderNumber, gSaleDisputeProduct.getOrderNumber()).orderByDesc(SaleShippingApplication::getOrderNumber).last("limit 1"));
                SaleReturnInventoryProduct gSaleReturnExchangeOrderDetail = new SaleReturnInventoryProduct();
                gSaleReturnExchangeOrderDetail.setOrderNumber(gSaleDisputeProduct.getOrderNumber());
                gSaleReturnExchangeOrderDetail.setProduct(gSaleDisputeProduct.getProductName());
                gSaleReturnExchangeOrderDetail.setProductSpecification(gSaleDisputeProduct.getProductSpecification());
                gSaleReturnExchangeOrderDetail.setReturnQuantity(gSaleDisputeProduct.getQuantity());
                if (saleShippingApplication != null) {
                    gSaleReturnExchangeOrderDetail.setDeliveryDate(saleShippingApplication.getShippingDate());
                }
                gSaleReturnExchangeOrderDetail.setTrayId(gSaleDisputeProduct.getTrayId());
                gSaleReturnExchangeOrderDetail.setGlassId(gSaleDisputeProduct.getGlassId());
                gSaleReturnExchangeOrderDetail.setIssueDescription(gSaleDisputeProduct.getIssueDescription());
                gSaleReturnExchangeOrderDetail.setRemark(gSaleDisputeProduct.getRemark());
                gSaleReturnExchangeOrderDetailList.add(gSaleReturnExchangeOrderDetail);
                gSaleReturnExchangeOrderDetail.setProductId(gSaleDisputeProduct.getProductId());
                allCount = allCount.add(gSaleDisputeProduct.getQuantity());
            }
        }
        GSaleReturnInventory gSaleReturnExchangeOrder = new GSaleReturnInventory();
        gSaleReturnExchangeOrder.setReturnNumber(returnNumber);
        gSaleReturnExchangeOrder.setDisputeNumber(gSaleDispute.getDisputeNumber());
        gSaleReturnExchangeOrder.setCustomer(gSaleDispute.getDisputerUnit());
        gSaleReturnExchangeOrder.setCustomer(gSaleDispute.getDisputerUnit());
        gSaleReturnExchangeOrder.setHandler((String) userMap.get(gSaleDispute.getCreateUserId()));
        gSaleReturnExchangeOrder.setHandlerId(gSaleDispute.getCreateUserId());
        gSaleReturnExchangeOrder.setDisputeId(gSaleDispute.getId());
        gSaleReturnExchangeOrder.setSaleReturnInventoryProductList(gSaleReturnExchangeOrderDetailList);
        return gSaleReturnExchangeOrder;
    }


    @Override
    public GSaleDispute getOneById(String id) {
        GSaleDispute gSaleDispute = baseMapper.selectById(id);
        List<GSaleDisputeProduct> saleDisputeProducts = gSaleDisputeProductMapper.selectList(Wrappers.<GSaleDisputeProduct>lambdaQuery()
                .eq(GSaleDisputeProduct::getDisputeId, id));
        gSaleDispute.setSaleDisputeProductList(saleDisputeProducts);

        ResultBody<List<FileBusiness>> fileBusinessesRs = fileApi.getFileBusinessByIds(Arrays.asList(id));
        if (fileBusinessesRs != null && CollectionUtils.isNotEmpty(fileBusinessesRs.getData())) {
            Map<String, FileBusiness> fileBusinessMap = fileBusinessesRs.getData().stream().collect(Collectors.toMap(f1 -> f1.getBusinessId().concat(""), fb -> fb, (f1, f2) -> f1));
            FileBusiness fileBusiness = fileBusinessMap.get(gSaleDispute.getId().concat(SALE_DISPUTE_FJ));
            if (fileBusiness != null) {
                gSaleDispute.setFilesIds(fileBusiness.getFileIds());
            }
            fileBusiness = fileBusinessMap.get(gSaleDispute.getId().concat(SALE_DISPUTE_DX_FJ));
            if (fileBusiness != null) {
                gSaleDispute.setFilesDCIds(fileBusiness.getFileIds());
            }
        }
        return gSaleDispute;
    }

    @Override
    public String getDisputeNumber() {
        GSaleDispute saleDispute = baseMapper.selectOne(Wrappers.<GSaleDispute>lambdaQuery().isNotNull(GSaleDispute::getDisputeNumber)
                .orderByDesc(GSaleDispute::getDisputeNumber).last("limit 1"));
        if (saleDispute == null) {
            String s = SerialDisputeNumberGenerator.generateNextSerialNumber(null);
            return s;
        }
        String s = DisputeNumberGenerator.generateOrderNumber(DisputeNumberGenerator.generateOrderNumber(saleDispute.getDisputeNumber()));
        return s;
    }


}
